package com.dragon.modules.yuegou.model.order;

import com.dragon.modules.yuegou.entity.order.OrderEntity;
import com.dragon.modules.yuegou.enums.order.OrderBuyerType;
import com.dragon.modules.yuegou.enums.order.OrderPayType;
import com.dragon.modules.yuegou.enums.order.OrderRefundStatus;
import com.dragon.modules.yuegou.enums.order.OrderSellerType;
import com.dragon.modules.yuegou.enums.order.OrderStatus;
import com.dragon.modules.yuegou.enums.order.OrderType;
import com.dragon.modules.yuegou.model.Owner;
import com.dragon.modules.yuegou.model.member.Member;
import com.dragon.modules.yuegou.model.merchant.Merchant;
import com.dragon.modules.yuegou.web.Check;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.collections4.CollectionUtils;
import org.hibernate.validator.constraints.Length;

import javax.annotation.Nullable;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.stream.Collectors;

/**
 * 订单模型类<br>
 * 
 * <p>
 * <h3>订单金额相关字段说明</h3>
 * <table border="1">
 * <tr>
 * <th>字段</th>
 * <th width="50">描述</th>
 * <th>公式</th>
 * <th>说明</th>
 * </tr>
 * <tr>
 * <td>amount</td>
 * <td>订单金额</td>
 * <td>订单金额 = 优惠金额 + 折扣金额 + 应付金额；<br>
 * 订单金额 = SUM(订单物品价格 * 数量)；<br>
 * </td>
 * <td>
 * 
 * </td>
 * <tr>
 * <td>points</td>
 * <td>订单积分</td>
 * <td></td>
 * <td>积分不存在折扣和优惠，所以订单积分就是应付积分</td>
 * </tr>
 * <tr>
 * <td>coupon_amount</td>
 * <td>优惠金额</td>
 * <td>优惠金额 = 订单金额 - 折扣金额 - 应付金额；<br>
 * 优惠金额 = SUM(订单优惠券优惠金额)；</td>
 * <td>优惠券的抵扣金额只和，目前的优惠券只有停车券一种，所以只有停车支付订单存在优惠金额</td>
 * </tr>
 * <tr>
 * <td>discount_amount</td>
 * <td>折扣金额</td>
 * <td>折扣金额 = 订单金额 - 优惠金额 - 应付金额；<br>
 * 折扣金额 = SUM((订单物品价格 - 订单物品折扣价) * 数量)<br>
 * </td>
 * <td>折扣金额与优惠金额的差别：<br>
 * 优惠金额对应了优惠券；折扣金额不对应优惠券，是通过商品降价、支付折扣等策略达到的。<br>
 * <p>
 * 存在折扣金额的场景：<br>
 * 1. 给SKU设置折扣价，例如价格100，折扣价80，如果购买一个这样的SKU，则订单金额为100，优惠金额为0，折扣金额为20，应付金额为80；<br>
 * 2. 商户打折，扫码支付一律9折，如果会员扫码支付100元，则订单金额为100，优惠金额为0，折扣金额为10，应付金额为90.<br>
 * <p>
 * 存在优惠金额的场景：<br>
 * 1. 会员使用停车券支付，例如会员停车产生费用20，使用一张20元停车抵扣券，则订单金额为20，优惠金额为20，折扣金额为0，应付金额为0.<br>
 * </td>
 * </tr>
 * <tr>
 * <td>payable_amount</td>
 * <td>应付金额</td>
 * <td>应付金额 = 订单金额 - 优惠金额 - 折扣金额；<br>
 * IF 已付款 THEN 应付金额 = 实付金额；<br>
 * </td>
 * <td>买家应该支付的金额，存在应付金额为0的特殊情况</td>
 * </tr>
 * <tr>
 * <td>pay_amount</td>
 * <td>实付金额</td>
 * <td>IF 已付款 THEN 实付金额 = 应付金额；</td>
 * <td>买家实际支付的金额，未支付的时候可能为0，付款完成则必然等于应付金额</td>
 * </tr>
 * <tr>
 * <td>pay_points</td>
 * <td>实付积分</td>
 * <td>IF 已付款 THEN 实付积分 = 订单积分；</td>
 * <td>买家实际支付的积分，未支付的时候可能为0，付款完成则必然等于订单积分</td>
 * </tr>
 * <tr>
 * <td>refund_amount</td>
 * <td>退款金额</td>
 * <td>退款金额 &lt;= 实付金额；<br>
 * 退款金额 = SUM(退款单退款金额)；</td>
 * <td>
 * 
 * </td>
 * </tr>
 * </table>
 * 
 * <p>
 * <h3>订单物品说明</h3>
 * <table border="1">
 * <tr>
 * <th>字段</th>
 * <th width="50">描述</th>
 * <th>公式</th>
 * <th>说明</th>
 * </tr>
 * <tr>
 * <td>order_item.sku_price</td>
 * <td>商品价格</td>
 * <td></td>
 * <td>商品价格即商品在本商城的单价。</td>
 * </tr>
 * <tr>
 * <td>order_item.sku_original_price</td>
 * <td>商品原价</td>
 * <td></td>
 * <td>商品原价也可以称为市场价，目的是为了跟商品价格对比，体现竞争优势。不会参与任何计算。</td>
 * </tr>
 * <tr>
 * <td>order_item.sku_discount_price</td>
 * <td>商品折扣价</td>
 * <td>IF 降价销售 THEN 商品折扣价 &lt;= 商品价格；<br>
 * ELSE 商品折扣价 = 商品价格；</td>
 * <td>目前存在两种降价销售的情况：1.秒杀、2.助力</td>
 * </tr>
 * <tr>
 * <td>order_item.sku_points</td>
 * <td>商品积分</td>
 * <td>IF 积分商城商品 THEN 商品积分 &gt;= 0；<br>
 * ELSE 商品积分 = 0；</td>
 * <td>商品的积分，当商品是积分商品是才会有积分。</td>
 * </tr>
 * <tr>
 * <td>order_item.num</td>
 * <td>商品数量</td>
 * <td>商品数量 &gt; 0</td>
 * <td>购买的商品数量</td>
 * </tr>
 * <tr>
 * <td>order_item.total_amount</td>
 * <td>总金额</td>
 * <td>总金额 = 商品折扣价 * 商品数量</td>
 * <td>总金额代表着这批商品的应该用多少钱购买；<br>
 * （商品价格 * 商品数量）代表着这批商品值多少钱；<br>
 * 折扣金额 =（商品价格 * 商品数量 - 商品折扣价 * 商品数量）；</td>
 * </tr>
 * <tr>
 * <td>order_item.total_points</td>
 * <td>总积分</td>
 * <td>总积分 = 商品积分 * 商品数量</td>
 * <td>总积分代表着这批商品应该用多少积分购买；</td>
 * </tr>
 * </table>
 * 
 * <p>
 * <h3>订单优惠券说明</h3>
 * <table border="1">
 * <tr>
 * <th>字段</th>
 * <th width="50">描述</th>
 * <th>公式</th>
 * <th>说明</th>
 * </tr>
 * <tr>
 * <td>order_coupon.amount</td>
 * <td>订单优惠券优惠金额</td>
 * <td>IF 是抵扣券 THEN 优惠金额 &lt;= 抵扣金额</td>
 * <td>优惠券理论上支持抵扣和折扣两种形式，目前只支持抵扣形式，停车券是一种抵扣券。</td>
 * </tr>
 * </table>
 * 
 * @author pbuilder generated
 * @date 2019-04-03 13:57:50
 * @company sgy
 * @version 2.0
 * @see Length 长度限制
 * @see NotNull 对象非空
 * @see NotEmpty 字符串、集合、表、数组非空
 */
public class Order extends OrderEntity {

	@ApiModelProperty("应结算价")
	private BigDecimal skuSettlementPrice;

	@ApiModelProperty("实结算价")
	private BigDecimal settlementPrice;

	@ApiModelProperty("平台分摊金额")
	private BigDecimal groupDivideFee;

	@ApiModelProperty("商户分摊金额")
	private BigDecimal merchantDivideFee;

	@ApiModelProperty("不使用优惠券")
	private boolean doNotUseCouponList = false;

	@ApiModelProperty("使用悦卡")
	private String cardTitle;
	
	@ApiModelProperty("商户")
	private String merchantName;// 商户

	@ApiModelProperty("卖家类型")
	private String sellerName;// 商户

	@ApiModelProperty("提交人")
	private String submitter;// 提交人

	@ApiModelProperty("子订单列表")
	private List<Order> orderList;// 子订单

	@ApiModelProperty("订单物品列表")
	private List<OrderItem> orderItemList;// 订单物品

	@ApiModelProperty("订单优惠券列表")
	private List<OrderCoupon> orderCouponList;
	
	@ApiModelProperty("单品列表")
	private List<Goods> goodsList;

	@ApiModelProperty("单品")
	private Goods goods;

	@ApiModelProperty("订单支付信息")
	private OrderPay orderPay;

	@ApiModelProperty("市场价")
	private BigDecimal marketPrice;

	@ApiModelProperty("订单商品数量")
	private Integer numberProducts;

	@ApiModelProperty("用户手机号")
	private String mobile;

	@ApiModelProperty("退款时间")
	private LocalDateTime refundTime;

	@ApiModelProperty("订单支付信息")
	private List<String> payMessage;

	@ApiModelProperty("是否支持悦卡支付")
	private Boolean yueCardPay;

	@ApiModelProperty("配送订单信息")
	private OrderShipping shipping;

	@ApiModelProperty("到家详情扩充信息")
	private GoHomeOrderReplenish replenish;

	@ApiModelProperty("商品名称")
	private String productName;
	
	@ApiModelProperty("商品规格")
	private String skuAttrs;

	@ApiModelProperty("支付方式")
	private String paymentMethod;

	public GoHomeOrderReplenish getReplenish() {
		return replenish;
	}

	public void setReplenish(GoHomeOrderReplenish replenish) {
		this.replenish = replenish;
	}

	public OrderShipping getShipping() {
		return shipping;
	}

	public void setShipping(OrderShipping shipping) {
		this.shipping = shipping;
	}

	public boolean isDoNotUseCouponList() {
		return doNotUseCouponList;
	}

	public void setDoNotUseCouponList(boolean doNotUseCouponList) {
		this.doNotUseCouponList = doNotUseCouponList;
	}

	public BigDecimal getGroupDivideFee() {
		return groupDivideFee;
	}

	public void setGroupDivideFee(BigDecimal groupDivideFee) {
		this.groupDivideFee = groupDivideFee;
	}

	public BigDecimal getMerchantDivideFee() {
		return merchantDivideFee;
	}

	public void setMerchantDivideFee(BigDecimal merchantDivideFee) {
		this.merchantDivideFee = merchantDivideFee;
	}

	public BigDecimal getSkuSettlementPrice() {
		return skuSettlementPrice;
	}

	public void setSkuSettlementPrice(BigDecimal skuSettlementPrice) {
		this.skuSettlementPrice = skuSettlementPrice;
	}

	public BigDecimal getSettlementPrice() {
		return settlementPrice;
	}

	public void setSettlementPrice(BigDecimal settlementPrice) {
		this.settlementPrice = settlementPrice;
	}

	public String getCardTitle() {
		return cardTitle;
	}

	public void setCardTitle(String cardTitle) {
		this.cardTitle = cardTitle;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}
	
	public String getSkuAttrs() {
		return skuAttrs;
	}

	public void setSkuAttrs(String skuAttrs) {
		this.skuAttrs = skuAttrs;
	}

	public String getPaymentMethod() {
		return paymentMethod;
	}

	public void setPaymentMethod(String paymentMethod) {
		this.paymentMethod = paymentMethod;
	}

	public Boolean getYueCardPay() {
		return yueCardPay;
	}

	public void setYueCardPay(Boolean yueCardPay) {
		this.yueCardPay = yueCardPay;
	}

	public LocalDateTime getRefundTime() {
		return refundTime;
	}

	public void setRefundTime(LocalDateTime refundTime) {
		this.refundTime = refundTime;
	}

	public List<String> getPayMessage() {
		return payMessage;
	}

	public void setPayMessage(List<String> payMessage) {
		this.payMessage = payMessage;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public String getMerchantName() {
		return merchantName;
	}

	public void setMerchantName(String merchantName) {
		this.merchantName = merchantName;
	}

	public String getSellerName() {
		return sellerName;
	}

	public void setSellerName(String sellerName) {
		this.sellerName = sellerName;
	}

	public String getSubmitter() {
		return submitter;
	}

	public void setSubmitter(String submitter) {
		this.submitter = submitter;
	}

	public Integer getNumberProducts() {
		return numberProducts;
	}

	public void setNumberProducts(Integer numberProducts) {
		this.numberProducts = numberProducts;
	}

	public List<Order> getOrderList() {
		return orderList;
	}

	public void setOrderList(List<Order> orderList) {
		this.orderList = orderList;
	}

	public List<OrderItem> getOrderItemList() {
		return orderItemList;
	}

	public void setOrderItemList(List<OrderItem> orderItemList) {
		this.orderItemList = orderItemList;
	}

	public List<OrderCoupon> getOrderCouponList() {
		return orderCouponList;
	}

	public void setOrderCouponList(List<OrderCoupon> orderCouponList) {
		this.orderCouponList = orderCouponList;
	}

	public List<Goods> getGoodsList() {
		return goodsList;
	}

	public void setGoodsList(List<Goods> goodsList) {
		this.goodsList = goodsList;
	}

	public Goods getGoods() {
		return goods;
	}

	public void setGoods(Goods goods) {
		this.goods = goods;
	}

	public OrderPay getOrderPay() {
		return orderPay;
	}

	public void setOrderPay(OrderPay orderPay) {
		this.orderPay = orderPay;
	}

	/**
	 * 构造一个空订单模型对象
	 */
	public Order() {
		super();
	}

	/**
	 * 依据实体对象的信息构造一个订单模型对象
	 * 
	 * @param entity 实体对象
	 */
	public Order(OrderEntity entity) {
		super(entity);
	}

	/**
	 * 依据其它对象的信息构造一个订单模型对象
	 * 
	 * @param other 其它对象
	 */
	public Order(Order other) {
		super(other);
	}

	@Override
	public String getId() {
		return id;
	}

	/**
	 * 设置订单号（其它表引用订单号使用order_no）
	 * 
	 * @param id 订单号（其它表引用订单号使用order_no）
	 * @return 当前对象
	 */
	public Order id(String id) {
		this.id = id;
		return this;
	}

	@Override
	public BigDecimal getAmount() {
		return amount;
	}

	/**
	 * 设置订单金额（订单物品金额之和)
	 * 
	 * @param amount 订单金额（订单物品金额之和)
	 * @return 当前对象
	 */
	public Order amount(BigDecimal amount) {
		this.amount = amount;
		return this;
	}

	@Override
	public Integer getPoints() {
		return points;
	}

	/**
	 * 设置订单积分
	 * 
	 * @param points 订单积分
	 * @return 当前对象
	 */
	public Order points(Integer points) {
		this.points = points;
		return this;
	}

	@Override
	public BigDecimal getCouponAmount() {
		return couponAmount;
	}

	/**
	 * 设置优惠金额（优惠金额之和）
	 * 
	 * @param couponAmount 优惠金额（优惠金额之和）
	 * @return 当前对象
	 */
	public Order couponAmount(BigDecimal couponAmount) {
		this.couponAmount = couponAmount;
		return this;
	}

	@Override
	public BigDecimal getDiscountAmount() {
		return discountAmount;
	}

	/**
	 * 设置折扣金额（ = SUM((订单物品价格 - 订单物品折扣价) * 数量)）
	 * 
	 * @param discountAmount 折扣金额（ = SUM((订单物品价格 - 订单物品折扣价) * 数量)）
	 * @return 当前对象
	 */
	public Order discountAmount(BigDecimal discountAmount) {
		this.discountAmount = discountAmount;
		return this;
	}

	@Override
	public BigDecimal getPayableAmount() {
		return payableAmount;
	}

    /**
	 * 设置应付金额 包含运费，运费存在ord_order_shipping
	 * 
	 * @param payableAmount 应付金额 包含运费，运费存在ord_order_shipping
	 * @return 当前对象
	 */
	public Order payableAmount(BigDecimal payableAmount) {
		this.payableAmount = payableAmount;
		return this;
	}

	@Override
	public BigDecimal getPayAmount() {
		return payAmount;
	}

	/**
	 * 设置实付金额
	 * 
	 * @param payAmount 实付金额
	 * @return 当前对象
	 */
	public Order payAmount(BigDecimal payAmount) {
		this.payAmount = payAmount;
		return this;
	}

	@Override
	public Integer getPayPoints() {
		return payPoints;
	}

	/**
	 * 设置积分支付额度
	 * 
	 * @param payPoints 积分支付额度
	 * @return 当前对象
	 */
	public Order payPoints(Integer payPoints) {
		this.payPoints = payPoints;
		return this;
	}

	@Override
	public OrderPayType getPayType() {
		return payType;
	}

    /**
	 * 设置[枚举]支付类型：0-其他-OTHER、1-悦卡-YUE_CARD、2-悦币-YUE_COIN、3-支付宝-ALIPAY、4-微信-WECHAT、5-积分-POINT
	 * 
	 * @param payType [枚举]支付类型：0-其他-OTHER、1-悦卡-YUE_CARD、2-悦币-YUE_COIN、3-支付宝-ALIPAY、4-微信-WECHAT、5-积分-POINT
	 * @return 当前对象
	 */
	public Order payType(OrderPayType payType) {
		this.payType = payType;
		return this;
	}

	@Override
	public OrderStatus getStatus() {
		return status;
	}

    /**
	 * 设置[枚举]订单状态：0-未付款-NOTPAY、1-已付款/待接单-PAID、2-已完成-SUCCEED、3-已关闭-CLOSED、4-已发货/配送中-SHIPPING、5-已过期-EXPIRED、6-待配送-WAITPOST
	 * 
	 * @param status [枚举]订单状态：0-未付款-NOTPAY、1-已付款/待接单-PAID、2-已完成-SUCCEED、3-已关闭-CLOSED、4-已发货/配送中-SHIPPING、5-已过期-EXPIRED、6-待配送-WAITPOST
	 * @return 当前对象
	 */
	public Order status(OrderStatus status) {
		this.status = status;
		return this;
	}

	@Override
	public BigDecimal getRefundAmount() {
		return refundAmount;
	}

	/**
	 * 设置退款金额
	 * 
	 * @param refundAmount 退款金额
	 * @return 当前对象
	 */
	public Order refundAmount(BigDecimal refundAmount) {
		this.refundAmount = refundAmount;
		return this;
	}

	@Override
	public OrderRefundStatus getRefundStatus() {
		return refundStatus;
	}

	/**
	 * 设置[枚举]退款状态：0-未退款-NO_REFUND、1-部分退款-PART_REFUND、2-完全退款-ALL_REFUND
	 * 
	 * @param refundStatus [枚举]退款状态：0-未退款-NO_REFUND、1-部分退款-PART_REFUND、2-完全退款-ALL_REFUND
	 * @return 当前对象
	 */
	public Order refundStatus(OrderRefundStatus refundStatus) {
		this.refundStatus = refundStatus;
		return this;
	}

	@Override
	public LocalDateTime getOrderTime() {
		return orderTime;
	}

	/**
	 * 设置下单时间
	 * 
	 * @param orderTime 下单时间
	 * @return 当前对象
	 */
	public Order orderTime(LocalDateTime orderTime) {
		this.orderTime = orderTime;
		return this;
	}

	@Override
	public LocalDateTime getCancelTime() {
		return cancelTime;
	}

	/**
	 * 设置取消时间
	 * 
	 * @param cancelTime 取消时间
	 * @return 当前对象
	 */
	public Order cancelTime(LocalDateTime cancelTime) {
		this.cancelTime = cancelTime;
		return this;
	}

	@Override
	public LocalDateTime getCloseTime() {
		return closeTime;
	}

	/**
	 * 设置交易关闭时间
	 * 
	 * @param closeTime 交易关闭时间
	 * @return 当前对象
	 */
	public Order closeTime(LocalDateTime closeTime) {
		this.closeTime = closeTime;
		return this;
	}

	@Override
	public LocalDateTime getPayTime() {
		return payTime;
	}

	/**
	 * 设置支付时间
	 * 
	 * @param payTime 支付时间
	 * @return 当前对象
	 */
	public Order payTime(LocalDateTime payTime) {
		this.payTime = payTime;
		return this;
	}

	@Override
	public LocalDateTime getPayExpireTime() {
		return payExpireTime;
	}

	/**
	 * 设置支付超时时间
	 * 
	 * @param payExpireTime 支付超时时间
	 * @return 当前对象
	 */
	public Order payExpireTime(LocalDateTime payExpireTime) {
		this.payExpireTime = payExpireTime;
		return this;
	}

	@Override
	public LocalDateTime getPickupExpireTime() {
		return pickupExpireTime;
	}

	/**
	 * 设置提货超时时间
	 * 
	 * @param pickupExpireTime 提货超时时间
	 * @return 当前对象
	 */
	public Order pickupExpireTime(LocalDateTime pickupExpireTime) {
		this.pickupExpireTime = pickupExpireTime;
		return this;
	}

	@Override
	public LocalDateTime getShippingTime() {
		return shippingTime;
	}

	/**
	 * 设置发货时间
	 * 
	 * @param shippingTime 发货时间
	 * @return 当前对象
	 */
	public Order shippingTime(LocalDateTime shippingTime) {
		this.shippingTime = shippingTime;
		return this;
	}

	@Override
	public LocalDateTime getEndTime() {
		return endTime;
	}

	/**
	 * 设置交易完成时间
	 * 
	 * @param endTime 交易完成时间
	 * @return 当前对象
	 */
	public Order endTime(LocalDateTime endTime) {
		this.endTime = endTime;
		return this;
	}

	@Override
	public OrderBuyerType getBuyerType() {
		return buyerType;
	}

	/**
	 * 设置[枚举]买家类型：0-会员-MEMBER、2-商户用户-MERCHANT_USER
	 * 
	 * @param buyerType [枚举]买家类型：0-会员-MEMBER、2-商户用户-MERCHANT_USER
	 * @return 当前对象
	 */
	public Order buyerType(OrderBuyerType buyerType) {
		this.buyerType = buyerType;
		return this;
	}

	@Override
	public String getBuyerId() {
		return buyerId;
	}

	/**
	 * 设置买家ID
	 * 
	 * @param buyerId 买家ID
	 * @return 当前对象
	 */
	public Order buyerId(String buyerId) {
		this.buyerId = buyerId;
		return this;
	}

	@Override
	public String getBuyerNick() {
		return buyerNick;
	}

	/**
	 * 设置卖家昵称
	 * 
	 * @param buyerNick 卖家昵称
	 * @return 当前对象
	 */
	public Order buyerNick(String buyerNick) {
		this.buyerNick = buyerNick;
		return this;
	}

	@Override
	public String getBuyerMessage() {
		return buyerMessage;
	}

	/**
	 * 设置卖家留言
	 * 
	 * @param buyerMessage 卖家留言
	 * @return 当前对象
	 */
	public Order buyerMessage(String buyerMessage) {
		this.buyerMessage = buyerMessage;
		return this;
	}

	@Override
	public OrderSellerType getSellerType() {
		return sellerType;
	}

	/**
	 * 设置[枚举]卖家类型：0-平台-PLATFORM、1-集团-GROUP、2-商圈-BUSD、3-商户-MERCHANT
	 * 
	 * @param sellerType [枚举]卖家类型：0-平台-PLATFORM、1-集团-GROUP、2-商圈-BUSD、3-商户-MERCHANT
	 * @return 当前对象
	 */
	public Order sellerType(OrderSellerType sellerType) {
		this.sellerType = sellerType;
		return this;
	}

	@Override
	public String getGroupId() {
		return groupId;
	}

	/**
	 * 设置集团ID
	 * 
	 * @param groupId 集团ID
	 * @return 当前对象
	 */
	public Order groupId(String groupId) {
		this.groupId = groupId;
		return this;
	}

	@Override
	public String getBusdId() {
		return busdId;
	}

	/**
	 * 设置商圈ID
	 * 
	 * @param busdId 商圈ID
	 * @return 当前对象
	 */
	public Order busdId(String busdId) {
		this.busdId = busdId;
		return this;
	}

	@Override
	public String getMerchantId() {
		return merchantId;
	}

	/**
	 * 设置商户ID
	 * 
	 * @param merchantId 商户ID
	 * @return 当前对象
	 */
	public Order merchantId(String merchantId) {
		this.merchantId = merchantId;
		return this;
	}

	@Override
	public String getParkId() {
		return parkId;
	}

	/**
	 * 设置停车场ID（停车支付订单专用）
	 * 
	 * @param parkId 停车场ID（停车支付订单专用）
	 * @return 当前对象
	 */
	public Order parkId(String parkId) {
		this.parkId = parkId;
		return this;
	}

	@Override
	public Boolean getIsVirtual() {
		return isVirtual;
	}

	/**
	 * 设置是否虚拟订单（1：虚拟订单，0：非虚拟订单，虚拟订单指所有商品都是虚拟商品的订单）
	 * 
	 * @param isVirtual 是否虚拟订单（1：虚拟订单，0：非虚拟订单，虚拟订单指所有商品都是虚拟商品的订单）
	 * @return 当前对象
	 */
	public Order isVirtual(Boolean isVirtual) {
		this.isVirtual = isVirtual;
		return this;
	}

	@Override
	public Boolean getPickup() {
		return pickup;
	}

	/**
	 * 设置是否需要上门自提（1：需要，会员自己上门自提，0：不需要）
	 * 
	 * @param pickup 是否需要上门自提（1：需要，会员自己上门自提，0：不需要）
	 * @return 当前对象
	 */
	public Order pickup(Boolean pickup) {
		this.pickup = pickup;
		return this;
	}

	@Override
	public Integer getPickupRemain() {
		return pickupRemain;
	}

	/**
	 * 设置剩余可提货数量
	 * 
	 * @param pickupRemain 剩余可提货数量
	 * @return 当前对象
	 */
	public Order pickupRemain(Integer pickupRemain) {
		this.pickupRemain = pickupRemain;
		return this;
	}

	@Override
	public Integer getLevel() {
		return level;
	}

	/**
	 * 设置订单层级（0：父订单，1：子订单，仅支持两级结构，子订单精确到卖家，一个订单可以包含多个卖家的商品，子订单中只会有一个卖家的商品）
	 * 
	 * @param level 订单层级（0：父订单，1：子订单，仅支持两级结构，子订单精确到卖家，一个订单可以包含多个卖家的商品，子订单中只会有一个卖家的商品）
	 * @return 当前对象
	 */
	public Order level(Integer level) {
		this.level = level;
		return this;
	}

	@Override
	public String getParentId() {
		return parentId;
	}

	/**
	 * 设置父订单ID
	 * 
	 * @param parentId 父订单ID
	 * @return 当前对象
	 */
	public Order parentId(String parentId) {
		this.parentId = parentId;
		return this;
	}

	@Override
	public OrderType getType() {
		return type;
	}

	/**
	 * 设置[枚举]类型：0-购物订单-BUY、1-扫码支付-SCAN_PAY、2-停车支付-PARK、3-商户停车券-MERCHANT_COUPON_BUY、4-购买悦卡-CARD_BUY、5-充值悦币-RECHARGE_COIN、6-仪表充值-DOORNO_RECHARGE、7-商户仪表充值-MERCHANT_DOORNO_RECHARGE、8-商户会员等级充值-MERCHANT_LEVEL_BUY、9-疯狂砍价-BARGAIN、10-秒杀-SECKILL、11-限时折扣-LIMIT_SALES、12-积分兑换-POINTS、13-购买套餐-MEAL、14-全民拼团-GROUPON、15-抽奖-LOTTERY、16-物业缴费-PROPERTY_PAY_COST、17-商户物业缴费-MERCHANT_PROPERTY_PAY_COST
	 *
	 * @param type [枚举]类型：0-购物订单-BUY、1-扫码支付-SCAN_PAY、2-停车支付-PARK、3-商户停车券-MERCHANT_COUPON_BUY、4-购买悦卡-CARD_BUY、5-充值悦币-RECHARGE_COIN、6-仪表充值-DOORNO_RECHARGE、7-商户仪表充值-MERCHANT_DOORNO_RECHARGE、8-商户会员等级充值-MERCHANT_LEVEL_BUY、9-疯狂砍价-BARGAIN、10-秒杀-SECKILL、11-限时折扣-LIMIT_SALES、12-积分兑换-POINTS、13-购买套餐-MEAL、14-全民拼团-GROUPON、15-抽奖-LOTTERY、16-物业缴费-PROPERTY_PAY_COST、17-商户物业缴费-MERCHANT_PROPERTY_PAY_COST
	 * @return 当前对象
	 */
	public Order type(OrderType type) {
		this.type = type;
		return this;
	}

	@Override
	public Boolean getLeaf() {
		return leaf;
	}

	public BigDecimal getMarketPrice() {
		return marketPrice;
	}

	public void setMarketPrice(BigDecimal marketPrice) {
		this.marketPrice = marketPrice;
	}

	/**
	 * 添加订单物品
	 * 
	 * @param skuId skuId
	 * @param num   数量
	 * @return this
	 */
	public Order addItem(String skuId, Integer num) {
		return addItem(skuId, num, null);
	}

	/**
	 * 添加订单物品
	 * 
	 * @param skuId         skuId
	 * @param num           数量
	 * @param discountPrice 折扣价，如果为null则会使用SKU中定义的折扣价；如果提供，则会覆盖SKU中的折扣价。
	 * @return this
	 */
	public Order addItem(String skuId, Integer num, @Nullable BigDecimal discountPrice) {
		Check.notNull(skuId, "skuId is required");
		Check.notNull(num, "num is required");
		if (this.orderItemList == null) {
			this.orderItemList = new ArrayList<>();
		}
		OrderItem item = new OrderItem();
		item.setSkuId(skuId);
		item.setNum(num);
		item.setSkuDiscountPrice(discountPrice);
		this.orderItemList.add(item);
		return this;
	}

	/**
	 * 添加优惠券
	 * 
	 * @param couponId 优惠券ID
	 * @return this
	 */
	public Order addCoupon(String couponId) {
		Check.notNull(couponId, "skuId is required");
		if (this.orderCouponList == null) {
			this.orderCouponList = new ArrayList<>();
		}
		OrderCoupon coupon = new OrderCoupon();
		coupon.setCouponId(couponId);
		this.orderCouponList.add(coupon);
		return this;
	}

	/**
	 * 计算订单金额<br>
	 * 订单金额、积分
	 */
	public void calculateAmountAndPoints() {
		if (leaf) {
			BigDecimal totalItemAmount = this.orderItemList.stream().map(OrderItem::getTotalAmount)
					.collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
			BigDecimal discountAmount = this.orderItemList.stream()
					.map(item -> item.getSkuPrice().subtract(item.getSkuDiscountPrice())
							.multiply(new BigDecimal(item.getNum())))
					.collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
			
			BigDecimal couponAmount = this.orderItemList.stream()
					.map(OrderItem::getCouponDiscountFee)
					.collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
			
			long totalItemPoints = this.orderItemList.stream()
					.collect(Collectors.summarizingInt(OrderItem::getSkuPoints)).getSum();
			
			this.amount = totalItemAmount;
			this.points = (int) totalItemPoints;
			this.discountAmount = discountAmount;
			this.couponAmount = couponAmount;
		} else {
			BigDecimal totalItemAmount = this.orderList.stream().map(Order::getAmount)
					.collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
			BigDecimal discountAmount = this.orderList.stream().map(Order::getDiscountAmount)
					.collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
			long totalItemPoints = this.orderList.stream().collect(Collectors.summarizingInt(Order::getPoints))
					.getSum();
			BigDecimal couponAmount = this.orderList.stream().map(Order::getCouponAmount)
					.collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
			
			this.amount = totalItemAmount;
			this.points = (int) totalItemPoints;
			this.discountAmount = discountAmount;
			this.couponAmount = couponAmount;
		}
	}

	/**
	 * 计算折扣金额
	 */
	public void calculateDiscountAmount() {
		if (leaf) {
			BigDecimal totalCouponAmount = this.orderItemList.stream()
					.map(OrderItem::getCouponDiscountFee)
					.collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
			this.couponAmount = totalCouponAmount;
		} else {
			BigDecimal totalCouponAmount = this.orderList.stream().map(Order::getCouponAmount)
					.collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add));
			
			this.couponAmount = totalCouponAmount;
		}
	}

	/**
	 * 列出孩子订单（包括自身）
	 * 
	 * @return 订单列表
	 */
	public List<Order> listWithChilds() {
		List<Order> orders = new LinkedList<>();
		// 宽度优先遍历
		Queue<Order> queue = new LinkedList<>();
		queue.add(this);
		while (!queue.isEmpty()) {
			Order order = queue.poll();
			orders.add(order);
			if (CollectionUtils.isNotEmpty(order.orderList)) {
				queue.addAll(order.orderList);
			}
		}
		return orders;
	}

	/**
	 * 列出所有的支付信息（包含子订单的）
	 * 
	 * @return 支付信息列表
	 */
	public List<OrderPay> listOrderPays() {
		return listWithChilds().stream().map(Order::getOrderPay).filter(Objects::nonNull).collect(Collectors.toList());
	}

	/**
	 * 列出所有订单物品（包括子订单的）<br>
	 * 
	 * @return 订单物品列表
	 */
	public List<OrderItem> listAllOrderItems() {
		return listWithChilds().stream().filter(o -> CollectionUtils.isNotEmpty(o.getOrderItemList()))
				.flatMap(o -> o.getOrderItemList().stream()).collect(Collectors.toList());
	}

	/**
	 * 列出所有订单单品（包括子订单的）<br>
	 * 
	 * @return 订单单品列表
	 */
	public List<Goods> listAllGoods() {
		return listWithChilds().stream().filter(o -> CollectionUtils.isNotEmpty(o.getGoodsList()))
				.flatMap(o -> o.getGoodsList().stream()).collect(Collectors.toList());
	}

	/**
	 * 列出所有订单优惠券（包括子订单的）<br>
	 * 
	 * @return 订单优惠券列表
	 */
	public List<OrderCoupon> listAllOrderCoupons() {
		return listWithChilds().stream().filter(o -> CollectionUtils.isNotEmpty(o.getOrderCouponList()))
				.flatMap(o -> o.getOrderCouponList().stream()).collect(Collectors.toList());
	}

	/**
	 * 设置卖家
	 * 
	 * @param seller 卖家
	 * @return this
	 */
	public Order setSeller(Owner seller) {
		this.sellerType = OrderSellerType.from(seller.getOwnerType().getCode());
		this.groupId = seller.getGroupId();
		this.busdId = seller.getBusdId();
		this.merchantId = seller.getMerchantId();
		return this;
	}

	/**
	 * 设置买家
	 * 
	 * @param memberBuyer 买家（会员）
	 * @return this
	 */
	public Order setMemberBuyer(Member memberBuyer) {
		this.buyerType = OrderBuyerType.MEMBER;
		this.buyerId = memberBuyer.getId();
		this.buyerNick = memberBuyer.getNickName();
		return this;
	}

	/**
	 * 设置买家
	 * 
	 * @param merchantBuyer 买家（商户用户）
	 * @return this
	 */
	public Order setMerchantBuyer(Merchant merchantBuyer) {
		this.buyerType = OrderBuyerType.MERCHANT_USER;
		this.buyerId = merchantBuyer.getId();
		this.buyerNick = merchantBuyer.getMerchantName();
		return this;
	}

	@Override
	public String getOldOrderNo() {
		return oldOrderNo;
	}

	/**
	 * 获取退款备注
	 * 
	 * @return refundRemarks 退款备注
	 */
	@Override
	public String getRefundRemarks() {
		return refundRemarks;
	}
  	
	/**
	 * 设置退款备注
	 * 
	 * @param refundRemarks 退款备注
	 */
	@Override
	public void setRefundRemarks(String refundRemarks) {
		this.refundRemarks = refundRemarks;
	}

	
	/**
	 * 设置旧订单号
	 * 
	 * @param oldOrderNo 旧订单号
	 * @return 当前对象
	 */
	public Order oldOrderNo(String oldOrderNo) {
		this.oldOrderNo = oldOrderNo;
		return this;
	}

}
